#ifndef _ENROLEE_STATE_H
#define _ENROLEE_STATE_H

#ifndef ETH_P_EAPOL
#define ETH_P_EAPOL 0x888e
#endif

typedef unsigned char                    LangIdx;

#define WLAN_SSID_LEN                    32
#define WLAN_KEY_PASSPHRASE_MAX          64
#define WLAN_SIMPLE_CONFIG_PIN_MAX       16
#define CFG_WLAN_PROFILE_NAME_SZ         16

#define CFG_SIMPLE_CONFIG_MANUFACTURER   "Atheros"
#define CFG_SIMPLE_CONFIG_MODEL_NAME     "Ventoux"
#define CFG_SIMPLE_CONFIG_MODEL_NUMBER   "1"
#define CFG_SIMPLE_CONFIG_DEVICE_NAME    "VoipPhone"


/* Message element types: */
#define simpleconfigMessageElement_ApChannel           0x1001  /* 2 bytes */
#define simpleconfigMessageElement_AssociationState    0x1002  /* 2 bytes */
#define simpleconfigMessageElement_AuthenticationType  0x1003  /* 2 bytes */
    /*AuthenticationType is one of the flag values below */
#define simpleconfigMessageElement_AuthenticationTypeFlags 0x1004  /* 2 bytes*/
    /*AuthenticationTypeFlags is a bit-or of flag values below */
    #define simpleconfigAuthenticationType_Open    0x0001
    #define simpleconfigAuthenticationType_WPAPSK  0x0002
    #define simpleconfigAuthenticationType_Shared  0x0004
    #define simpleconfigAuthenticationType_WPA     0x0008   /* not PSK? */
    #define simpleconfigAuthenticationType_WPA2    0x0010   /* not PSK? */
    #define simpleconfigAuthenticationType_WPA2PSK 0x0020
#define simpleconfigMessageElement_Authenticator       0x1005  /* 8 bytes */
#define simpleconfigMessageElement_ConfigMethods       0x1008  /* 2 bytes */
#define simpleconfigMessageElement_ConfigurationError  0x1009  /* 2 bytes */
    #define simpleconfigConfigurationError_NoError  0
    #define simpleconfigConfigurationError_OOBInterfaceReadError 1
    #define simpleconfigConfigurationError_DecryptionCRCFailure  2
    #define simpleconfigConfigurationError_2dot4ChannelNotSupported 3
    #define simpleconfigConfigurationError_5dot0ChannelNotSupported 4
    #define simpleconfigConfigurationError_SignalTooWeak         5
    #define simpleconfigConfigurationError_NetworkAuthFailure    6
    #define simpleconfigConfigurationError_NetworkAssociationFailure 7
    #define simpleconfigConfigurationError_NoDHCPREsponse        8
    #define simpleconfigConfigurationError_FailedDHCPConfig      9
    #define simpleconfigConfigurationError_IPAddressConflict    10
    #define simpleconfigConfigurationError_CouldNotConnectToRegistrar 11
    #define simpleconfigConfigurationError_MultiplerPBCSessionsDetected 12
    #define simpleconfigConfigurationError_RogueActivitySuspected 13
    #define simpleconfigConfigurationError_DeviceBusy            14
    #define simpleconfigConfigurationError_SetupLocked           15
    #define simpleconfigConfigurationError_MessageTimeout        16
    #define simpleconfigConfigurationError_RegistrationSessionTimeout 17
    #define simpleconfigConfigurationError_DevicePasswordAuthFailure 18
    const char *simpleconfigConfigurationErrorMessages[] = {
        [simpleconfigConfigurationError_NoError] = 
                                       "NoError",
        [simpleconfigConfigurationError_OOBInterfaceReadError] =
                                       "OOBInterfaceReadError",
        [simpleconfigConfigurationError_DecryptionCRCFailure] = 
                                       "DecryptionCRCFailure",
        [simpleconfigConfigurationError_2dot4ChannelNotSupported] = 
                                       "2dot4ChannelNotSupported",
        [simpleconfigConfigurationError_5dot0ChannelNotSupported] =
                                       "5dot0ChannelNotSupported",
        [simpleconfigConfigurationError_SignalTooWeak] = 
                                       "SignalTooWeak",
        [simpleconfigConfigurationError_NetworkAuthFailure] = 
                                       "NetworkAuthFailure",
        [simpleconfigConfigurationError_NetworkAssociationFailure] =
                                       "NetworkAssociationFailure",
        [simpleconfigConfigurationError_NoDHCPREsponse] = 
                                       "NoDHCPREsponse",
        [simpleconfigConfigurationError_FailedDHCPConfig] = 
                                       "FailedDHCPConfig",
        [simpleconfigConfigurationError_IPAddressConflict] = 
                                       "IPAddressConflict",
        [simpleconfigConfigurationError_CouldNotConnectToRegistrar] = 
                                       "CouldNotConnectToRegistrar",
        [simpleconfigConfigurationError_MultiplerPBCSessionsDetected] = 
                                       "MultiplerPBCSessionsDetected",
        [simpleconfigConfigurationError_RogueActivitySuspected] = 
                                       "RogueActivitySuspected",
        [simpleconfigConfigurationError_DeviceBusy] = 
                                       "DeviceBusy",
        [simpleconfigConfigurationError_SetupLocked] = 
                                       "SetupLocked",
        [simpleconfigConfigurationError_MessageTimeout] = 
                                       "MessageTimeout",
        [simpleconfigConfigurationError_RegistrationSessionTimeout] = 
                                       "RegistrationSessionTimeout",
        [simpleconfigConfigurationError_DevicePasswordAuthFailure] = 
                                       "DevicePasswordAuthFailure",
    };
#define simpleconfigMessageElement_ConfirmationUrl4    0x100A  /* <= 64 bytes*/
#define simpleconfigMessageElement_ConfirmationUrl6    0x100B  /* <= 76 bytes*/
#define simpleconfigMessageElement_ConnectionType      0x100C  /* 1 byte */
#define simpleconfigMessageElement_ConnectionTypeFlags 0x100D  /* 1 byte */
#define simpleconfigMessageElement_Credential          0x100E
#define simpleconfigMessageElement_EncryptionType      0x100F  /* 2 bytes */
    #define simpleconfigEncryptType_None        0x0001
    #define simpleconfigEncryptType_WEP         0x0002
    #define simpleconfigEncryptType_TKIP        0x0004
    #define simpleconfigEncryptType_AES         0x0008
#define simpleconfigMessageElement_EncryptionTypeFlags 0x1010  /* 2 bytes */
#define simpleconfigMessageElement_DeviceName          0x1011  /* <= 32 bytes*/
#define simpleconfigMessageElement_DevicePasswordId    0x1012  /* 2 bytes */
    #define simpleconfigPasswordId_PIN          0x0000
    #define simpleconfigPasswordId_UserSpecified 0x0001
    #define simpleconfigPasswordId_MachineSpecifed 0x0002
    #define simpleconfigPasswordId_Rekey        0x0003
    #define simpleconfigPasswordId_PushButton   0x0004
    #define simpleconfigPasswordId_RegistrarSpecified 0x0005
#define simpleconfigMessageElement_EHash1              0x1014  /* 32 bytes */
#define simpleconfigMessageElement_EHash2              0x1015  /* 32 bytes */
#define simpleconfigMessageElement_ESNonce1            0x1016  /* 16 bytes */
#define simpleconfigMessageElement_ESNonce2            0x1017  /* 16 bytes */
#define simpleconfigMessageElement_EncryptedSettings   0x1018
#define simpleconfigMessageElement_EnrolleeNonce       0x101A  /* 16 bytes */
#define simpleconfigMessageElement_FeatureId           0x101B  /* 4 bytes */
#define simpleconfigMessageElement_Identity            0x101C  /* <= 80 bytes*/
#define simpleconfigMessageElement_IdentityProof       0x101D
#define simpleconfigMessageElement_KeyWrapAuthenticator 0x101E  /* 8 bytes*/
#define simpleconfigMessageElement_KeyIdentifier       0x101F  /* 16 bytes*/
#define simpleconfigMessageElement_MacAddress          0x1020  /* 6 bytes */
#define simpleconfigMessageElement_Manufacturer        0x1021  /* <= 64 bytes*/
#define simpleconfigMessageElement_MessageType         0x1022  /* 1 byte */
    #define simpleconfigMessageType_Beacon 1
    #define simpleconfigMessageType_ProbeRequest 2
    #define simpleconfigMessageType_ProbeResponse 3
    #define simpleconfigMessageType_M1 4
    #define simpleconfigMessageType_M2 5
    #define simpleconfigMessageType_M2D 6
    #define simpleconfigMessageType_M3 7
    #define simpleconfigMessageType_M4 8
    #define simpleconfigMessageType_M5 9
    #define simpleconfigMessageType_M6 10
    #define simpleconfigMessageType_M7 11
    #define simpleconfigMessageType_M8 12
    #define simpleconfigMessageType_Ack 13
    #define simpleconfigMessageType_Nack 14
    #define simpleconfigMessageType_Done 15
#define simpleconfigMessageElement_ModelName           0x1023  /* <= 32 bytes*/
#define simpleconfigMessageElement_ModelNumber         0x1024  /* <= 32 bytes*/
#define simpleconfigMessageElement_NetworkIndex        0x1026  /* 1 byte */
#define simpleconfigMessageElement_NetworkKey          0x1027  /* <= 64 bytes*/
#define simpleconfigMessageElement_NetworkKeyIndex     0x1028  /* 1 byte */
#define simpleconfigMessageElement_NewDeviceName       0x1029  /* <= 32 bytes*/
#define simpleconfigMessageElement_NewPassword         0x102A  /* <= 64 bytes*/
#define simpleconfigMessageElement_OOBDevicePassword   0x102C  /* <= 58 bytes*/
#define simpleconfigMessageElement_OSVersion           0x102D  /* 4 bytes */
#define simpleconfigMessageElement_PowerLevel          0x102F  /* 1 byte */
#define simpleconfigMessageElement_PskCurrent          0x1030  /* 1 byte */
#define simpleconfigMessageElement_PskMax              0x1031  /* 1 byte */
#define simpleconfigMessageElement_PublicKey           0x1032 /* <= 192 bytes*/
#define simpleconfigMessageElement_RadioEnabled        0x1033  /* bool */
#define simpleconfigMessageElement_Reboot              0x1034  /* bool */
#define simpleconfigMessageElement_RegistrarCurrent    0x1035  /* 1 byte */
#define simpleconfigMessageElement_RegistrarEstablished 0x1036  /* bool */
#define simpleconfigMessageElement_RegistrarList       0x1037 /* <= 512 bytes*/
#define simpleconfigMessageElement_RegistrarMax        0x1038  /* 1 byte */
#define simpleconfigMessageElement_RegistrarNonce      0x1039  /* 16 bytes */
#define simpleconfigMessageElement_RequestType         0x103A  /* 1 byte */
#define simpleconfigMessageElement_ResponseType        0x103B  /* 1 byte */
#define simpleconfigMessageElement_RFBands             0x103C  /* 1 byte */
#define simpleconfigMessageElement_RHash1              0x103D  /* 32 bytes */
#define simpleconfigMessageElement_RHash2              0x103E  /* 32 bytes */
#define simpleconfigMessageElement_RSNonce1            0x103F  /* 16 bytes */
#define simpleconfigMessageElement_RSNonce2            0x1040  /* 16 bytes */
#define simpleconfigMessageElement_SelectedRegistrar   0x1041  /* bool */
#define simpleconfigMessageElement_SerialNumber        0x1042  /* <= 32 bytes*/
#define simpleconfigMessageElement_WiFiProtectedSetupState 0x1044  /* 1 byte */
#define simpleconfigMessageElement_Ssid                0x1045  /* 32 bytes */
#define simpleconfigMessageElement_TotalNetworks       0x1046  /* 1 byte */
#define simpleconfigMessageElement_UuidE               0x1047  /* 16 bytes */
#define simpleconfigMessageElement_UuidR               0x1048  /* 16 bytes */
#define simpleconfigMessageElement_VendorExtension     0x1049 /*<= 1024 bytes*/
#define simpleconfigMessageElement_Version             0x104A  /* 1 byte */
#define     simpleconfigVersionEncoding (1<<4)
#define simpleconfigMessageElement_X509CertificateRequest 0x104B
#define simpleconfigMessageElement_X509Certificate     0x104C
#define simpleconfigMessageElement_EapIdentity         0x104D /* <= 64 bytes */
#define simpleconfigMessageElement_MessageCounter      0x104E  /* 8 bytes */
#define simpleconfigMessageElement_PublicKeyHash       0x104F  /* 20 bytes */
#define simpleconfigMessageElement_RekeyKey            0x1050  /* 32 bytes */
#define simpleconfigMessageElement_KeyLifetime         0x1051  /* 4 bytes */
#define simpleconfigMessageElement_PermittedConfigMethods 0x1052  /* 2 bytes */
#define simpleconfigMessageElement_SelectedRegistrarConfigMethods 0x1053  /* 2 bytes */
#define simpleconfigMessageElement_PrimaryDeviceType   0x1054  /* 8 bytes */
#define simpleconfigMessageElement_SecondaryDeviceTypeList 0x1055 /*<= 128 bytes*/
#define simpleconfigMessageElement_PortableDevice      0x1056  /* bool */
#define simpleconfigMessageElement_ApSetupLocked       0x1057  /* bool */
#define simpleconfigMessageElement_ApplicationExtension 0x1058  /* <= 512 bytes */
#define simpleconfigMessageElement_EapType             0x1059  /* <= 8 bytes */
#define simpleconfigMessageElement_InitializationVector 0x1060  /* 32 bytes */
#define simpleconfigMessageElement_KeyProvidedAutomatically 0x1061  /* bool */
#define simpleconfigMessageElement_8021xEnabled        0x1062  /* bool */
#define simpleconfigMessageElement_AppSessionKey       0x1063 /* <= 128 bytes*/
#define simpleconfigMessageElement_WepTransmitKey      0x1064  /* 1 byte */

/* Performance constants. These can be changed. 
 *      The calculation time for each stage can be on the order of
 *      4 seconds or so... take this in account.
 *      There is also an overall limit of 120 seconds per WPS standard
 *      enforced separately.
 */
#define SIMPLECONFIG_REPLY_TIMEOUT_SECONDS 7  /* retry after timeout */
#define SIMPLECONFIG_MAX_TRIES             5  /* no. of retries before restart */
#define SIMPLECONFIG_MAX_STARTS            2  /* max no. of (re)starts */

/* Algorithm constants. These must be standard. */
#define SIMPLECONFIG_HMAC_BLOCK_SIZE       64
#define SIMPLECONFIG_SHA256_OUTPUT_SIZE    32
#define SIMPLECONFIG_PRIVATE_KEY_SIZE      192
#define SIMPLECONFIG_PUBLIC_KEY_SIZE       192
#define SIMPLECONFIG_NONCE_SIZE            16
#define SIMPLECONFIG_DHKEY_SIZE            32  /* == SIMPLECONFIG_SHA256_OUTPUT_SIZE */
#define SIMPLECONFIG_AUTHKEY_SIZE          32
#define SIMPLECONFIG_KEYWRAPKEY_SIZE       16
#define SIMPLECONFIG_KEYWRAPAUTHENTICATOR_SIZE 8
#define SIMPLECONFIG_EMSK_SIZE             32
#define SIMPLECONFIG_PSK_SIZE              16  /* SIMPLECONFIG_SHA256_OUTPUT_SIZE/2 */
#define SIMPLECONFIG_EHASH_SIZE            32   /* == SIMPLECONFIG_SHA256_OUTPUT_SIZE */
#define SIMPLECONFIG_AES_BLOCK_SIZE        16
#define SIMPLECONFIG_IV_SIZE               16 /* MUST == SIMPLECONFIG_AES_BLOCK_SIZE */
#define SIMPLECONFIG_UIID_SIZE             16

enum simpleconfigState
{
    simpleconfigState_eOff = 0, // must be zero
    simpleconfigState_eStart = 1,       // EAPOL start message (will be) sent
    simpleconfigState_eIdentity = 2,    // identity response rcvd
    simpleconfigState_eM1 = 3,          // M1 (will be) sent
    simpleconfigState_eM2 = 4,          // M2 rcvd (not processed yet)
    simpleconfigState_eM3 = 5,          // M3 (will be) sent
    simpleconfigState_eM4 = 6,          // M4 rcvd (not processed yet)
    simpleconfigState_eM5 = 7,          // M5 (will be) sent
    simpleconfigState_eM6 = 8,          // M6 rcvd (not processed yet)
    simpleconfigState_eM7 = 9,          // M7 (will be) sent
    simpleconfigState_eM8 = 10,         // M8 rcvd (not processed yet)
    simpleconfigState_eDone = 11,       // Done (will be) sent
};

const char *simpleconfigStateNames[] =
{
    [simpleconfigState_eOff] = "Off",
    [simpleconfigState_eStart] = "Start",
    [simpleconfigState_eIdentity] = "Identity",
    [simpleconfigState_eM1] = "M1",
    [simpleconfigState_eM2] = "M2",
    [simpleconfigState_eM3] = "M3",
    [simpleconfigState_eM4] = "M4",
    [simpleconfigState_eM5] = "M5",
    [simpleconfigState_eM6] = "M6",
    [simpleconfigState_eM7] = "M7",
    [simpleconfigState_eM8] = "M8",
    [simpleconfigState_eDone] = "Done",
};

struct simpleconfigResults {
    /* The following are found from the "Credential" message
     * embodied in e.g. M8 message.
     */
    unsigned ApChannel;
    unsigned AuthenticationType;
    unsigned AuthenticationTypeFlags;
    unsigned EncryptionType;
    unsigned EncryptionTypeFlags;
    unsigned char ssid[WLAN_SSID_LEN + 1]; /* null terminated? */
    unsigned char NetworkKey[64];
    int NetworkKeyLen;
    int WepTransmitKeyIdx;
    unsigned ConnectionTypeFlags; /* Use this? */
    unsigned RegistarConfigMethods; /* Use this? */
    char Ssid[WLAN_SSID_LEN];
    unsigned char RegistrarUuid[SIMPLECONFIG_UIID_SIZE]; /* use this? */
};

/* EAP message header
 */
struct simpleconfigEapMessageHeader
{
#if 0
    /* The following fields are the ethernet header format we use
     */
    unsigned char EthernetDestAddr[6];
    unsigned char EthernetSrcAddr[6];
    unsigned short EthernetProtocol;          /* htons: 0x888e for EAPOL */
    #define simpleconfigEthernetHeaderSize 14

    /* The following fields are defined in 802.1X for EAPOL.
     */
    unsigned char EapolProtocolVersion; 
        #define simpleconfigEapolProtocolVersion 1  /* or use latest == 2? */
    unsigned char EapolPacketType;   /* 0=EAP packet, 1=EAPOL start ... */
        #define simpleconfigEapolPacketType_EAP 0  /* EAP packet */
        #define simpleconfigEapolPacketType_Start 1 
    unsigned short EapolPacketBodyLength;    /* htons: nbytes of what follows */
    #define simpleconfigEapolHeaderSize (simpleconfigEthernetHeaderSize+4)
#endif

    /* EAP packet starts here.
     */
    #define simpleconfigEapStartOffset simpleconfigEapolHeaderSize
    /* The next 3 fields are defined by RFC 3748 (EAP) for all EAP packets.
     * This applies only for EAPOL packet type 0 (EAP packet).
     * NOTE that Code==3 (success) is never used, since SimpleConfig
     * always fails to authenticate... it's purpose is the side affect
     * of setting up the configuration that can be used to authenticate.
     */
    unsigned char EapCode;    /* 1 for requests, 2 for response, 4 for failure */
        #define simpleconfigEapCode_Request 1
        #define simpleconfigEapCode_Response 2
        #define simpleconfigEapCode_Failure 4
    unsigned char EapIdentifier;   /* correlate response w/ request */
    unsigned short EapLength;    /* htons: overall length of eap packet (bytes) */
    #define simpleconfigEapBasicHeaderSize (simpleconfigEapolHeaderSize+4)

    /*  The EapType field is used for EapCode==request or EapCode==response.
     *  A type of 254 is "expanded type"...
     */
    unsigned char EapType;         /* EAP method type == 254 (expanded type) */
        #define simpleconfigEapType_Identity 1
        #define simpleconfigEapType_Expanded 254
    #define simpleconfigEapResponseHeaderSize \
                            (simpleconfigEapBasicHeaderSize+1)

    /* The EapVendorId and VendorType* fields are used for EAP expanded types.
     *  The values indicate that this is SimpleConfig.
     */
    unsigned char EapVendorId[3];  /* use 0x00372A (for WFA) */
        #define simpleconfigHeaderVendorId 0x00372A
    /* Just in case we somehow don't get 4 byte alignment, i'm
     * breaking VendorType up in two.
     */
    unsigned short EapVendorTypeHigh;   /* Use 0 */
    unsigned short EapVendorTypeLow;   /* htons: Use 0x00000001 */
        #define simpleconfigEapVendorType_SimpleConfig 1
    #define simpleconfigEapExpandedHeaderSize \
                            (simpleconfigEapResponseHeaderSize+7)

    /* The remaining fields are defined for SimpleConfig only */
    unsigned char SimpleConfigOpCode;
        #define simpleconfigSimpleConfigOpcode_Start 1
        #define simpleconfigSimpleConfigOpcode_Ack   2
        #define simpleconfigSimpleConfigOpcode_Nack  3
        #define simpleconfigSimpleConfigOpcode_Msg   4        /* for M1 to M8 */
        #define simpleconfigSimpleConfigOpcode_Done  5
        #define simpleconfigSimpleConfigOpcode_FragAck 6
    unsigned char SimpleConfigFlags;
        #define simpleconfigSimpleConfigFlags_MoreFragments 1
            /* means more fragments of packet are coming */
            /* must reply with FrackAck for each fragment other than last */
        #define simpleconfigSimpleConfigFlags_LengthField   2
    #if 0       /* following for fragmentation; not implemented in intel reference design so not here either */
    unsigned short SimpleConfigMessageLength;       /* htons: len of following message */
        /* IFF LengthField flag set,
         * this gives total message length; must be present
         * in first packet only.
         * If LengthField flag is not set, this field is OMITTED.
         */
    #endif
    /* NOTE: message follows immediately.
     * The message consists of information elements.
     */
}__attribute__ ((packed));

/* Our state data */
struct simpleconfigS
{
    /**********************************************************************
     * Overall state information:
     */
    int IsInit;
    enum simpleconfigState State;  /* where in state machine we are */
    int IsConnected;          /* if we have connection to the AP */
    unsigned StartSeconds;    /* when we started */
    int NStarts;              /* how many (re)starts */
    int NTries;               /* how many tries at same state */
    int Success;              /* If we succeeded... */
    int Failure;              /* If we gave up... */
    int NErrors;              /* cumulative no. of errors */
    int FakeSuccess;          /* Hack! ignore some errors. Set with debugger */
    void (*StatusCB)(void);   /* call back on status changes */
    /* error from job remembered in LastError.
     *  As a quick hack (TODO: fix) i'm putting some messages into
     *  LastErrMsg instead.
     */
    LangIdx LastError;
    char LastErrMsg[80];
    //struct pollerTask Timer;
    //int IsBound;     /* true if we are registered with lwipethernet */
    //struct lwipethernetBind Bind;       /* binding information */
    unsigned char ApAddr[6];         /* The AP's mac address */
    unsigned char OurAddr[6];    /* copy of our mac address */

    /**********************************************************************
     * Misc. resulting information. 
     * The new configuration is based on this.
     * LastResults preserves last SUCCESSful results for debugging...
     */
    int ResultCnt;
    struct simpleconfigResults Results[8];
    struct simpleconfigResults LastResults;

    /**********************************************************************
     * Passwords, keys, nonces
     */
    int PushButtonMethod;       /* nonzero to use insecure push button method*/
    char Pin[WLAN_SIMPLE_CONFIG_PIN_MAX+1];   /* non-empty unless PushButtonMethod */
    unsigned char OurUuid[SIMPLECONFIG_NONCE_SIZE];  /* our universal identifier based on mac addr*/
    unsigned char OurNonce[SIMPLECONFIG_NONCE_SIZE]; /* our random number for this session */
    unsigned char OurPrivateKey[SIMPLECONFIG_PRIVATE_KEY_SIZE];
    unsigned OurPrivateKeyLen;
    unsigned char OurPublicKey[SIMPLECONFIG_PUBLIC_KEY_SIZE];
    unsigned OurPublicKeyLen;
    unsigned char RegistrarNonce[SIMPLECONFIG_NONCE_SIZE]; /* registrar's random number for this session */
    unsigned char RegistrarPublicKey[SIMPLECONFIG_PUBLIC_KEY_SIZE];
    unsigned RegistrarPublicKeyLen;
    unsigned char DHSecret[SIMPLECONFIG_PUBLIC_KEY_SIZE];  /* aka g^AB mod p */
    unsigned DHSecretLen;
    unsigned char DHKey[SIMPLECONFIG_DHKEY_SIZE];       /* sha256(DHSecret) */
    unsigned char KDK[SIMPLECONFIG_SHA256_OUTPUT_SIZE]; /* Key derivation key*/
    unsigned char ENonce1[SIMPLECONFIG_NONCE_SIZE]; /* a random number for this session */
    unsigned char ENonce2[SIMPLECONFIG_NONCE_SIZE]; /* a random number for this session */
    unsigned char RNonce1[SIMPLECONFIG_NONCE_SIZE]; /* from registrar */
    unsigned char RNonce2[SIMPLECONFIG_NONCE_SIZE]; /* from registrar */
    unsigned char AuthKey[SIMPLECONFIG_AUTHKEY_SIZE];
    unsigned char KeyWrapKey[SIMPLECONFIG_KEYWRAPKEY_SIZE];
    unsigned char Psk1[SIMPLECONFIG_PSK_SIZE];
    unsigned char Psk2[SIMPLECONFIG_PSK_SIZE];
    unsigned char EHash1[SIMPLECONFIG_EHASH_SIZE];
    unsigned char EHash2[SIMPLECONFIG_EHASH_SIZE];
    unsigned char RHash1[SIMPLECONFIG_EHASH_SIZE];
    unsigned char RHash2[SIMPLECONFIG_EHASH_SIZE];

    /**********************************************************************
     * Message buffers 
     * For now, i have a separate buffer for each as it may(?) 
     * help with debugging.
     * TODO: FIX: It is of course wasteful of memory.
     * CAREFUL! The buffers MUST be word aligned..... even though
     * they are declared as unsigned char.
     */
    unsigned char RcvdPkt[1600];    /* last rcvd packet, minus ethernet hdr*/
    int RcvdPktLen;                 /* nbytes in RcvdPkt */
    unsigned LastEapIdentifier;
    unsigned char IdentityPkt[1600]; /* Identity packet we send */
    int IdentityPktLen;               /* nbytes in IdentityPkt */
    unsigned char StartPkt[1600];   /* Start message we send */
    int StartPktLen;                 /* nbytes in StartPkt */
    unsigned char ACK[1600];   /* M1 message we send, incl. full hdr */
    int ACKLen;                 /* nbytes in M1[] */
    unsigned char M1[1600];   /* M1 message we send, incl. full hdr */
    int M1Len;                 /* nbytes in M1[] */
    unsigned char M2[1600];   /* M2 message we rcvd, incl. full hdr */
    int M2Len;                 /* nbytes in M2[] */
    unsigned char M3[1600];   /* M3 message we send, incl. full hdr */
    int M3Len;                 /* nbytes in M3[] */
    unsigned char M4[1600];   /* M4 message we rcvd, incl. full hdr */
    int M4Len;                 /* nbytes in M4[] */
    unsigned char M4e[1600];   /* M4 (de!)crypted settings we recvd */
    int M4eLen;                 /* nbytes in M4e[] */
    unsigned char M5[1600];   /* M5 message we send, incl. full hdr */
    int M5Len;                 /* nbytes in M5[] */
    unsigned char M5e[1600];   /* M5 uncrypted settings we encrypt */
    int M5eLen;                 /* nbytes in M5e[] */
    unsigned char M6[1600];   /* M6 message we rcvd, incl. full hdr */
    int M6Len;                 /* nbytes in M6[] */
    unsigned char M6e[1600];   /* M6 encrypted part */
    int M6eLen;                 /* nbytes in M6e[] */
    unsigned char M7[1600];   /* M7 message we send, incl. full hdr */
    int M7Len;                 /* nbytes in M7[] */
    unsigned char M7e[1600];   /* M7 message, encrypted part */
    int M7eLen;                 /* nbytes in M7e[] */
    unsigned char M8[1600];   /* M8 message we rcvd, incl. full hdr */
    int M8Len;                 /* nbytes in M8[] */
    unsigned char M8e[1600];   /* M8 message , encrypted part */
    int M8eLen;                 /* nbytes in M8e[] */
    unsigned char DonePkt[1600];   /* Done message we send, incl. full hdr */
    int DonePktLen;                 /* nbytes in Done[] */
    unsigned char NackPkt[1600];   /* Nack message we send, incl. full hdr */
    int NackPktLen;                 /* nbytes in NackPkt[] */
};

/* Per WSP standard:
 * The 1536 bit MODP group used by Wi-Fi Protected Setup 
 * is taken from RFC 3526.
 * The generator is: 2.
 *
 * How many bits should be used for the (randomly generated) private key?
 * WSC reference code by way of openssl appears to use 1 less than the
 * number of bits in the P... why? ... see SIMPLECONFIG_PUBLIC_KEY_SIZE above
 * for implementation of this... although i use same number of bits.
 */
/* Big endian byte array representing Diffie-Helman power p
 * which is used for public key generation.
 */
static const unsigned char simpleconfigDhP[] =
{
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
/* Big endian byte array representing Diffie-Hellman generator g
 * which is used for public key generation.
 */
static const unsigned char simpleconfigDhG[] = { 0x02 };

#endif
